package org.rain.common.util.json;

import org.rain.common.util.json.status.EndState;

import java.util.*;

/**
 * created by yangtong on 2025/4/14 22:51:17
 * <br/>
 * json对象字符串解析状态机，每个json对应一个状态机，线程不安全
 */
public class JsonFsm {
    //状态机的起始状态
    private JsonState state = JsonState.START;
    //当前的json字符串
    private final String jsonStr;
    //json字符串长度
    private final int jsonLength;
    //当前遍历到的索引
    private int pos = 0;
    //中间缓存
    StringBuilder buffer = new StringBuilder();
    //希望从value读到的目标字符串
    private String targetLiteral = null;
    //当前的key
    private String key = null;
    //当前遍历到的字符
    char c;

    //存储json解析过程中的结果
    final Deque<Object> contextStack = new ArrayDeque<>();
    //当前正处于哪种json结构里面
    private final Deque<ContextType> typeStack = new ArrayDeque<>();

    public JsonFsm(String jsonStr) {
        this.jsonStr = jsonStr;
        this.jsonLength = jsonStr.length();
    }

    public Object parseJsonStr() {
        while (pos < jsonLength) {
            c = jsonStr.charAt(pos++);
            state.handle(this, c);
        }
        if (!(state instanceof EndState)) {
            throw new RuntimeException("JSON 结构不完整，未以 【}、]】 结束");
        }
        pos = 0;
        state = JsonState.START;
        //完整的数据，被压在最底层
        return contextStack.getLast();
    }

    public void changeState(JsonState newState) {
        this.state = newState;
    }

    public String getBuffer() {
        //TODO 待优化
        return buffer.toString();
    }

    public Integer getBufferLength() {
        return buffer.length();
    }

    public void writeBuffer() {
        buffer.append(c);
    }

    public void writeBuffer(char _c) {
        buffer.append(_c);
    }

    public void cleanBuffer() {
        buffer.setLength(0);
    }

    public void setKey() {
        if (buffer.isEmpty()) {
            throw new RuntimeException("尝试写入的key为null");
        }
        key = buffer.toString();
        cleanBuffer();
    }

    public void targetLiteral(String literal) {
        this.targetLiteral = literal;
    }

    public String currentTargetLiteral() {
        return targetLiteral;
    }

    public void nesting(ContextType type) {
        Object structure;
        if (type == ContextType.OBJECT) {
            structure = new HashMap<String, Object>();
        } else if (type == ContextType.ARRAY) {
            structure = new ArrayList<Object>();
        } else {
            throw new IllegalStateException("未知结构类型: " + type);
        }

        if (!typeStack.isEmpty()) {
            //把结构作为当前key的value加入上层结构
            acceptValue(structure);
        }

        contextStack.push(structure);
        //将当前json上下文类型压栈
        typeStack.push(type);
    }

    public int deNesting() {
        typeStack.pop();
        contextStack.pop();
        return typeStack.size();
    }

    public ContextType currentEnv() {
        return typeStack.peek();
    }

    public void acceptValue(Object value) {
        if (typeStack.peek() == ContextType.OBJECT) {
            ((Map<String, Object>) contextStack.peek()).put(key, value);
        } else if (typeStack.peek() == ContextType.ARRAY) {
            ((List<Object>) contextStack.peek()).add(value);
        } else {
            throw new IllegalStateException("未知结构栈顶");
        }
        key = null;
    }
}
